package br.com.klis.batendoumabola.client.presenter;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import br.com.klis.batendoumabola.client.event.SignInEvent;
import br.com.klis.batendoumabola.client.event.UploadEvent;
import br.com.klis.batendoumabola.client.service.PeladaServiceAsync;
import br.com.klis.batendoumabola.client.util.Helper;
import br.com.klis.batendoumabola.client.widgets.ContentVerticalPanel;
import br.com.klis.batendoumabola.client.widgets.EastVerticalPanel;
import br.com.klis.batendoumabola.client.widgets.FooterHorizontalPanel;
import br.com.klis.batendoumabola.client.widgets.MenuVerticalPanel;
import br.com.klis.batendoumabola.shared.BateBolaVerifier;
import br.com.klis.batendoumabola.shared.LoginInfo;
import br.com.klis.batendoumabola.shared.Pelada;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.maps.client.geocode.Geocoder;
import com.google.gwt.maps.client.geocode.LatLngCallback;
import com.google.gwt.maps.client.geom.LatLng;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;

public class PeladasPresenter implements Presenter {

	private List<Pelada> peladas = new ArrayList<Pelada>();
	private String telaDeOrigem = "";
	private static final String TELA_MEUS_RESULTADOS = "meus";
	private static final String TELA_RESULTADOS = "pesquisa";

	public interface Display {
		HasClickHandlers getSignIn();
		HasClickHandlers getSignOut();
		HasClickHandlers getList();

		// Menu
		MenuVerticalPanel getMenuPanel();
		// Content
		ContentVerticalPanel getContentPanel();
		// Footer
		FooterHorizontalPanel getFooterPanel();
		// East
		EastVerticalPanel getEastPanel();

		Widget asWidget();
	}

	private final PeladaServiceAsync rpcService;
	private final HandlerManager eventBus;
	private final Display display;
	private Pelada pelada;
	private LoginInfo loginInfo;

	public PeladasPresenter(PeladaServiceAsync rpcService, HandlerManager eventBus, Display view, LoginInfo loginInfo) {
		this.rpcService = rpcService;
		this.eventBus = eventBus;
		this.display = view;
		this.loginInfo = loginInfo;
	}

	public void bind() {
		display.getSignIn()
		.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				GWT.log("entrou no manipulador do click do link SignIn...");
				GWT.log("disparando o evento SignInEvent...");
				eventBus.fireEvent(new SignInEvent());
			}
		});
		
		display.getContentPanel().getDeleteImage().addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if(loginInfo.isLoggedIn()){
					deleteSelectedPeladas();
				}else{
					Window.alert("Por favor, autentique-se primeiro.");
				}
				
			}
		});

		display.getList().addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				int selectedRow = display.getContentPanel().getClickedRow(event);

				if (selectedRow >= 0) {
					String id = peladas.get(selectedRow).getId().toString();
					rpcService.getPeladaById(id, new AsyncCallback<Pelada>() {
					      public void onSuccess(Pelada result) {
					    	  pelada = result;
					    	  display.getContentPanel().getIdTextBox().setValue(pelada.getId().toString());
					    	  display.getContentPanel().getNomeTextBox().setValue(pelada.getNome());
					    	  display.getContentPanel().getDescricaoTextArea().setValue(pelada.getDescricao());
					    	  display.getContentPanel().getDataDateBox().setValue(pelada.getData());
					    	  display.getContentPanel().getLocalTextBox().setValue(pelada.getLocal());
					    	  display.getContentPanel().getLogradouroTextBox().setValue(pelada.getLogradouro());
					    	  display.getContentPanel().getNumeroTextBox().setValue(pelada.getNumero());
					    	  display.getContentPanel().getBairroTextBox().setValue(pelada.getBairro());
					    	  display.getContentPanel().getCidadeTextBox().setValue(pelada.getCidade());
					    	  display.getContentPanel().getEstadoTextBox().setValue(pelada.getEstado());
					    	  display.getContentPanel().getTemVagasCheckBox().setValue(pelada.getTemVagas());
					    	  display.getContentPanel().getGratuitoCheckBox().setValue(pelada.getGratuito());
					    	  display.getContentPanel().setFormEdicao(pelada.getNome());
					    	  GWT.log("loginInfo: "+loginInfo.getEmailAddress());
					    	  GWT.log("user: "+pelada.getUser());
					    	  if (loginInfo.isLoggedIn()){
					    		  if(loginInfo.getEmailAddress().equals(pelada.getUser())){
						    		  display.getContentPanel().setFormEdicaoEnabled(true);
						    	  }else{
						    		  display.getContentPanel().setFormEdicaoEnabled(false);
						    	  }
					    	  }else{
					    		  display.getContentPanel().setFormEdicaoEnabled(false);
					    	  }
					    	  //eventBus.fireEvent(new EditPeladaEvent());
					      }
					      
					      public void onFailure(Throwable error) {
					        //Window.alert("Error retrieving pelada");
					    	  Helper.handleError(error,loginInfo);
					      }
					 });
				}
			}
		});
		
		display.getContentPanel().getAtualizarDadosAdmButton()
		.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				doAtualizarDadosAdm();
			}
		});

		display.getMenuPanel().getHomeMenuItem().setCommand(new Command() {
			public void execute() {
				display.getContentPanel().setFormPesquisa("Procurando um Bate-Bola?");
			}
		});
		
		display.getMenuPanel().getNovoBateBolaMenuItem()
				.setCommand(new Command() {
					public void execute() {
						display.getContentPanel().reset();
						display.getContentPanel().setFormEdicao("Novo Bate-Bola");
						//eventBus.fireEvent(new AddPeladaEvent());
					}
				});
		
		display.getMenuPanel().getMeusBateBolasMenuItem()
				.setCommand(new Command() {
					public void execute() {
						getPeladasByLoggedUser();
						telaDeOrigem = TELA_MEUS_RESULTADOS;
						//display.getContentPanel().setAsFormPesquisa();
						//Window.alert("N�o implementado! Meus");
					}
				});
		
		display.getMenuPanel().getUploadMenuItem()
		.setCommand(new Command() {
			public void execute() {
				eventBus.fireEvent(new UploadEvent());
			}
		});

		display.getContentPanel().getSaveButton()
				.addClickHandler(new ClickHandler() {
					public void onClick(ClickEvent event) {
						doSave();
					}
				});

		display.getContentPanel().getCancelButton()
				.addClickHandler(new ClickHandler() {
					public void onClick(ClickEvent event) {
						doCancelEdicao();
						//eventBus.fireEvent(new EditPeladaCancelledEvent());
					}
				});
		
		display.getContentPanel().getSearchButton()
		.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				pesquisarPeladas();
				//eventBus.fireEvent(new EditPeladaCancelledEvent());
			}
		});
		
		display.getContentPanel().getShowMapButton()
		.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				showMapa();
				//eventBus.fireEvent(new EditPeladaCancelledEvent());
			}
		});
		
		/*display.getContentPanel().getSubmit()
		.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				GWT.log("Button submit has been pressed.");
				display.getContentPanel().getForm().submit();
				//eventBus.fireEvent(new EditPeladaCancelledEvent());
			}
		});*/
		
		/*// Add an event handler to the form.
		display.getContentPanel().getForm()
	    .addSubmitHandler(new FormPanel.SubmitHandler() {
	      public void onSubmit(SubmitEvent event) {
	    	  GWT.log("The form has been submited.");
	        // This event is fired just before the form is submitted. We can take
	        // this opportunity to perform validation.
	        if (tb.getText().length() == 0) {
	          Window.alert("The text box must not be empty");
	          event.cancel();
	        }
	      }
	    });
		
		display.getContentPanel().getForm()
	    .addSubmitCompleteHandler(new FormPanel.SubmitCompleteHandler() {
	      public void onSubmitComplete(SubmitCompleteEvent event) {
	    	  GWT.log("The form submit has been completed.");
	        // When the form submission is successfully completed, this event is
	        // fired. Assuming the service returned a response of type text/html,
	        // we can get the result text here (see the FormPanel documentation for
	        // further explanation).
	        Window.alert(event.getResults());
	      }
	    });*/
		
	}

	public void go(final HasWidgets container) {
		bind();
		container.clear();
		container.add(display.asWidget());
	}

	public void sortPeladas() {

		// Yes, we could use a more optimized method of sorting, but the
		// point is to create a test case that helps illustrate the higher
		// level concepts used when creating MVP-based applications.
		//
		for (int i = 0; i < peladas.size(); ++i) {
			for (int j = 0; j < peladas.size() - 1; ++j) {
				if (peladas.get(j).getNome()
						.compareToIgnoreCase(peladas.get(j + 1).getNome()) >= 0) {
					Pelada tmp = peladas.get(j);
					peladas.set(j, peladas.get(j + 1));
					peladas.set(j + 1, tmp);
				}
			}
		}
		//Collections.sort(peladas);
	}

	public void setPeladas(List<Pelada> vPeladas) {
		this.peladas = vPeladas;
	}

	public Pelada getPelada(int index) {
		return peladas.get(index);
	}

	private void deleteSelectedPeladas() {
		List<Integer> selectedRows = display.getContentPanel().getSelectedRows();
		ArrayList<Pelada> ids = new ArrayList<Pelada>();
		

		for (int i = 0; i < selectedRows.size(); ++i) {
			Pelada tempPelada = peladas.get(selectedRows.get(i)-1);
			if (loginInfo.getEmailAddress().equals(tempPelada.getUser())){
				ids.add(tempPelada);	
			}
		}
		
		if (ids.size() == 0){
			Window.alert("Por favor, selecione ao menos um Bate-Bola");
		}else{
			rpcService.deletePeladas(ids, new AsyncCallback<ArrayList<Pelada>>() {
				public void onSuccess(ArrayList<Pelada> result) {
					peladas = result;
					sortPeladas();
					display.getContentPanel().setMeusResultados(peladas);
				}

				public void onFailure(Throwable error) {
					//Window.alert("Error deleting selected contacts");
					Helper.handleError(error,loginInfo);
				}
			});	
		}
		
	}

	//TODO Melhorar as consist�ncias de campo
	private void doSave() {
		pelada = getPeladaDaTela();
		
		String retorno = BateBolaVerifier.isValid(pelada);
		if (retorno != ""){
			Window.alert(retorno);
		}else{
				rpcService.savePelada(pelada, new AsyncCallback<Pelada>() {
					public void onSuccess(Pelada result) {
						if (pelada.getId() == null || pelada.getId().equals("")){
							peladas.add(result);	
						}else{
							for(int i=0;i<peladas.size();i++){
								if(pelada.getId().equals(peladas.get(i).getId())){
									peladas.set(i, result);	
								}
							}
						}
						pelada = result;
						sortPeladas();
						display.getContentPanel().setMeusResultados(peladas);
						//eventBus.fireEvent(new PeladaUpdatedEvent(result));
					}

					public void onFailure(Throwable error) {
						Helper.handleError(error,loginInfo);
					}
				});	
			//}
	}
		
			
}
	private Pelada getPeladaDaTela(){
		Pelada peladaDaTela = new Pelada();
		String id = display.getContentPanel().getIdTextBox().getValue();
		if (id != null && !id.equals("")){
			peladaDaTela.setId(new Long(id));
		}
		String nome = display.getContentPanel().getNomeTextBox().getValue();
		peladaDaTela.setNome(nome);
		String descricao = display.getContentPanel().getDescricaoTextArea().getValue();
		peladaDaTela.setDescricao(descricao);
		Date data = display.getContentPanel().getDataDateBox().getValue();
		GWT.log("DATA OBTIDA DA TELA: "+data);
		peladaDaTela.setData(data);
		String local = display.getContentPanel().getLocalTextBox().getValue();
		peladaDaTela.setLocal(local);
		String logradouro = display.getContentPanel().getLogradouroTextBox().getValue();
		peladaDaTela.setLogradouro(logradouro);
		String numero = display.getContentPanel().getNumeroTextBox().getValue();
		peladaDaTela.setNumero(numero);
		String bairro = display.getContentPanel().getBairroTextBox().getValue();
		peladaDaTela.setBairro(bairro);
		String cidade = display.getContentPanel().getCidadeTextBox().getValue();
		peladaDaTela.setCidade(cidade);
		String estado = display.getContentPanel().getEstadoTextBox().getValue();
		peladaDaTela.setEstado(estado);
		Boolean temVagas = display.getContentPanel().getTemVagasCheckBox().getValue();
		if (temVagas == null){
			temVagas = false;
		}
		peladaDaTela.setTemVagas(temVagas);
		Boolean gratuito = display.getContentPanel().getGratuitoCheckBox().getValue();
		if (gratuito == null){
			gratuito = false;
		}
		peladaDaTela.setGratuito(gratuito);
		return peladaDaTela;
	}

	
	private void doCancelEdicao(){
		if(telaDeOrigem.equals(TELA_MEUS_RESULTADOS)){
			display.getContentPanel().cancelaFormEdicaoMeus();	
		}else{
			display.getContentPanel().cancelaFormEdicaoDefault();
		}
	}

	private void pesquisarPeladas() {
		telaDeOrigem = TELA_RESULTADOS;
		Pelada pelada = new Pelada();
		pelada.setNome(display.getContentPanel().getQualTextBox().getValue());
		pelada.setData(display.getContentPanel().getQuandoDateBox().getValue());
		pelada.setCidade(display.getContentPanel().getOndeTextBox().getValue());
		pelada.setLocal(display.getContentPanel().getOndeLocalTextBox().getValue());
		pelada.setTemVagas(display.getContentPanel().getDetalheVagas());
		pelada.setGratuito(display.getContentPanel().getDetalheGratuito());
		GWT.log("Pesquisar Peladas - tem vagas: "+pelada.getTemVagas());
		GWT.log("Pesquisar Peladas - gratuito: "+pelada.getGratuito());
		rpcService.pesquisarPeladas(pelada, new AsyncCallback<ArrayList<Pelada>>() {
			public void onFailure(Throwable error) {
				Helper.handleError(error,loginInfo);
			}

			public void onSuccess(ArrayList<Pelada> pels) {
				peladas = pels;
				display.getContentPanel().setResultados(peladas);
			}
		});
	}
	
	private void getPeladasByLoggedUser() {
		rpcService.getPeladasByLoggedUser(new AsyncCallback<ArrayList<Pelada>>() {
			public void onFailure(Throwable error) {
				Helper.handleError(error,loginInfo);
			}

			public void onSuccess(ArrayList<Pelada> pels) {
				peladas = pels;
				display.getContentPanel().setMeusResultados(peladas);
			}
		});
	}
	
	private void showMapa(){
		Geocoder geocoder = new Geocoder();
		Pelada pTela = getPeladaDaTela();
		final String address = pTela.getNumero()+","+pTela.getLogradouro()+","+pTela.getBairro()+","+pTela.getCidade()+","+pTela.getEstado();
	    geocoder.getLatLng(address, new LatLngCallback() {
			
			@Override
			public void onSuccess(LatLng point) {
				GWT.log("Retornou coordenadas: "+point);
				display.getContentPanel().geraMapa(address, point);
			}
			
			@Override
			public void onFailure() {
				Window.alert("Desculpe, não conseguimos processar esse endereço.");
			}
		});
	}
	
	private void doAtualizarDadosAdm(){
		rpcService.atualizarDadosAdm(new AsyncCallback<Boolean>() {
			public void onSuccess(Boolean result) {
				if (result){
					Window.alert("Operação executada com sucesso.");
				}
			}

			public void onFailure(Throwable error) {
				Helper.handleError(error,loginInfo);
			}
		});	
	}
}